<template>
  <transition name="msgbox-fade">
    <div
      class="yun-message-box__wrapper"
      tabindex="-1"
      v-show="visible"
      @click.self="handleWrapperClick"
      role="dialog"
      aria-modal="true"
      :aria-label="title || 'dialog'">
      <div class="yun-message-box" :class="[customClass, center && 'yun-message-box--center']">
        <div class="yun-message-box__header" v-if="title !== null">
          <div class="yun-message-box__title">
            <div
              :class="['yun-message-box__status', icon]"
              v-if="icon && center">
            </div>
            <span>{{ title }}</span>
          </div>
          <button
            type="button"
            class="yun-message-box__headerbtn"
            aria-label="Close"
            v-if="showClose"
            @click="handleAction(distinguishCancelAndClose ? 'close' : 'cancel')"
            @keydown.enter="handleAction(distinguishCancelAndClose ? 'close' : 'cancel')">
            <i class="yun-message-box__close iconfont yun-icon--close1"></i>
          </button>
        </div>
        <div class="yun-message-box__content">
          <div class="yun-message-box__container">
            <div
              :class="['yun-message-box__status', icon]"
              v-if="icon && !center && message !== ''">
            </div>
            <div class="yun-message-box__message" v-if="message !== ''">
              <slot>
                <p v-if="!dangerouslyUseHTMLString" class="yun-message-box__message_word">{{ message }}</p>
                <p v-else v-html="message"></p>
              </slot>
            </div>
          </div>
          <div class="yun-message-box__input" v-show="showInput">
            <!--<yun-input-->
              <!--v-model="inputValue"-->
              <!--:type="inputType"-->
              <!--@keydown.enter.native="handleInputEnter"-->
              <!--:placeholder="inputPlaceholder"-->
              <!--ref="input"></yun-input>-->
            <div class="yun-message-box__errormsg" :style="{ visibility: !!editorErrorMessage ? 'visible' : 'hidden' }">{{ editorErrorMessage }}</div>
          </div>
        </div>
        <div class="yun-message-box__btns">

          <div
            @click="handleAction('confirm')"
            @keydown.enter="handleAction('confirm')"
            class="yun-message-box__btn1"
            ref="confirm"
            :class="[ confirmButtonClasses ]"
            v-show="showConfirmButton"
            >
            {{ confirmButtonText || '确认' }}
          </div>
          <div
            :loading="cancelButtonLoading"
            class="yun-message-box__btn2"
            v-if="showCancelButton"
            @click="handleAction('cancel')"
            @keydown.enter="handleAction('cancel')">
            {{ cancelButtonText || '取消'}}
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>

<script type="text/babel">
  import { addClass, removeClass } from '../../../../action/utils/dom';
  import Dialog from '../../../../action/utils/aria-dialog';

  let messageBox;
  let typeMap = {
    success: 'success',
    info: 'info',
    warning: 'warning',
    error: 'error'
  };

  export default {
    // mixins: [Popup, Locale],

    props: {
      modal: {
        default: true
      },
      lockScroll: {
        default: true
      },
      showClose: {
        type: Boolean,
        default: true
      },
      closeOnClickModal: {
        default: true
      },
      closeOnPressEscape: {
        default: true
      },
      closeOnHashChange: {
        default: true
      },
      center: {
        default: false,
        type: Boolean
      },
      roundButton: {
        default: false,
        type: Boolean
      }
    },

    components: {
      // ElInput,
      // ElButton
    },

    computed: {
      icon() {
        const { type, iconClass } = this;
        return iconClass || (type && typeMap[type] ? `yun-icon-${ typeMap[type] }` : '');
      },

      confirmButtonClasses() {
        return `yun-button--primary ${ this.confirmButtonClass }`;
      },
      cancelButtonClasses() {
        return `${ this.cancelButtonClass }`;
      }
    },

    methods: {
      getSafeClose() {
        const currentId = this.uid;
        return () => {
          this.$nextTick(() => {
            if (currentId === this.uid) this.doClose();
          });
        };
      },
      doClose() {
        if (!this.visible) return;
        this.visible = false;
        this._closing = true;

        this.onClose && this.onClose();
        messageBox.closeDialog(); // 解绑
        if (this.lockScroll) {
          setTimeout(this.restoreBodyStyle, 200);
        }
        this.opened = false;
       // this.doAfterClose();

      },

      handleWrapperClick() {
        if (this.closeOnClickModal) {
          this.handleAction(this.distinguishCancelAndClose ? 'close' : 'cancel');
        }
      },

      handleInputEnter() {
        if (this.inputType !== 'textarea') {
          return this.handleAction('confirm');
        }
      },

      handleAction(action) {
        if (action === 'confirm') {
          setTimeout(() => {
            if (action) this.callback(action, this);
          });
          this.doClose();
        }else{
          this.action = action;
          if (typeof this.beforeClose === 'function') {
            this.close = this.getSafeClose();
            this.beforeClose(action, this, this.close);
          } else {
            this.doClose();
          }
        }

      },

      validate() {
        if (this.$type === 'prompt') {
          const inputPattern = this.inputPattern;
          if (inputPattern && !inputPattern.test(this.inputValue || '')) {
            this.editorErrorMessage = this.inputErrorMessage || t('el.messagebox.error');
            addClass(this.getInputElement(), 'invalid');
            return false;
          }
          const inputValidator = this.inputValidator;
          if (typeof inputValidator === 'function') {
            const validateResult = inputValidator(this.inputValue);
            if (validateResult === false) {
              this.editorErrorMessage = this.inputErrorMessage || t('el.messagebox.error');
              addClass(this.getInputElement(), 'invalid');
              return false;
            }
            if (typeof validateResult === 'string') {
              this.editorErrorMessage = validateResult;
              addClass(this.getInputElement(), 'invalid');
              return false;
            }
          }
        }
        this.editorErrorMessage = '';
        removeClass(this.getInputElement(), 'invalid');
        return true;
      },
      getFirstFocus() {
        const btn = this.$el.querySelector('.yun-message-box__btns .yun-button');
        const title = this.$el.querySelector('.yun-message-box__btns .yun-message-box__title');
        return btn || title;
      },
      getInputElement() {
        const inputRefs = this.$refs.input.$refs;
        return inputRefs.input || inputRefs.textarea;
      },
      handleClose() {
        this.handleAction('close');
      }
    },

    watch: {
      inputValue: {
        immediate: true,
        handler(val) {
          this.$nextTick(_ => {
            if (this.$type === 'prompt' && val !== null) {
              this.validate();
            }
          });
        }
      },

      visible(val) {
        if (val) {

          this.uid++;
          if (this.$type === 'alert' || this.$type === 'confirm') {
            this.$nextTick(() => {
              // this.$refs.confirm.$el.focus();
             });
          }
          this.focusAfterClosed = document;
          messageBox = new Dialog(this.$el, this.focusAfterClosed, this.getFirstFocus());
        }

        // prompt
        if (this.$type !== 'prompt') return;
        if (val) {
          setTimeout(() => {
            if (this.$refs.input && this.$refs.input.$el) {
              this.getInputElement().focus();
            }
          }, 500);
        } else {
          this.editorErrorMessage = '';
          removeClass(this.getInputElement(), 'invalid');
        }
      }
    },

    mounted() {
      this.$nextTick(() => {
        if (this.closeOnHashChange) {
          window.addEventListener('hashchange', this.close);
        }
      });
    },

    beforeDestroy() {
      if (this.closeOnHashChange) {
        window.removeEventListener('hashchange', this.close);
      }
      setTimeout(() => {
        messageBox.closeDialog();
      });
    },

    data() {
      return {
        uid: 1,
        title: undefined,
        message: '',
        visible:false,
        type: '',
        iconClass: '',
        customClass: '',
        showInput: false,
        inputValue: null,
        inputPlaceholder: '',
        inputType: 'text',
        inputPattern: null,
        inputValidator: null,
        inputErrorMessage: '',
        showConfirmButton: true,
        showCancelButton: true,
        action: '',
        confirmButtonText: '',
        cancelButtonText: '',
        confirmButtonLoading: false,
        cancelButtonLoading: false,
        confirmButtonClass: '',
        confirmButtonDisabled: false,
        cancelButtonClass: '',
        editorErrorMessage: null,
        callback: null,
        dangerouslyUseHTMLString: false,
        focusAfterClosed: null,
        isOnComposition: false,
        distinguishCancelAndClose: false
      };
    }
  };
</script>


<style lang="scss">
  /* MessageBox
-------------------------- */
  $--color-primary: #409EFF !default;
  /// color|1|Functional Color|1
  $--color-success: #67C23A !default;
  /// color|1|Functional Color|1
  $--color-warning: #E6A23C !default;
  /// color|1|Functional Color|1
  $--color-danger: #F56C6C !default;
  /// color|1|Functional Color|1
  $--color-info: #909399 !default;

  /// color||Color|0
  $--messagebox-title-color: #303133 !default;
  $--msgbox-width: 384px !default;
  $--msgbox-border-radius: 4px !default;
  /// fontSize||Font|1
  $--messagebox-font-size: 18px !default;
  /// fontSize||Font|1
  $--messagebox-content-font-size: 14px !default;
  /// color||Color|0
  $--messagebox-content-color: #606266 !default;
  /// fontSize||Font|1
  $--messagebox-error-font-size: 12px !default;
  $--msgbox-padding-primary: 15px !default;
  /// color||Color|0
  $--messagebox-success-color: $--color-success !default;
  /// color||Color|0
  $--messagebox-info-color: $--color-info !default;
  /// color||Color|0
  $--messagebox-warning-color: $--color-warning !default;
  /// color||Color|0
  $--messagebox-danger-color: $--color-danger !default;
  $--message-close-size:16px !default;
  .yun-message-box__wrapper {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    text-align: center;
    z-index: 9000;
    background-color: rgba(33,41,44,.4);
    &::after {
      content: "";
      display: inline-block;
      height: 100%;
      width: 0;
      vertical-align: middle;
    }
  }
  .yun-message-box{
    display: inline-block;
    width: $--msgbox-width;
    padding-bottom: 10px;
    vertical-align: middle;
    background-color: #ffffff;
    border-radius: $--msgbox-border-radius;
    border: 1px solid #EBEEF5;
    font-size: $--messagebox-font-size;
    box-shadow:  0 2px 12px 0 rgba(0, 0, 0, 0.1);
    text-align: left;
    overflow: hidden;
    backface-visibility: hidden;



   .yun-message-box__header {
    position: relative;
    padding: $--msgbox-padding-primary;
    padding-bottom: 10px;
  }

   .yun-message-box__title {
    padding-left: 0;
    margin-bottom: 0;
    font-size: $--messagebox-font-size;
    line-height: 1;
    color: $--messagebox-title-color;
  }

   .yun-message-box__headerbtn {
    position: absolute;
    top: $--msgbox-padding-primary;
    right: $--msgbox-padding-primary;
    padding: 0;
    border: none;
    outline: none;
    background: transparent;
    font-size: $--message-close-size;
    cursor: pointer;

    .yun-message-box__close {
      color: $--color-info;
    }

  &:focus, &:hover {
    .yun-message-box__close {
      color: $--color-primary;
    }
  }

  }

    .yun-message-box__content {
    padding: 10px $--msgbox-padding-primary;
    color: $--messagebox-content-color;
    font-size: $--messagebox-content-font-size;
  }

    .yun-message-box__container {
    position: relative;
  }

    .yun-message-box__input{
    padding-top: 15px;

  & input.invalid {
      border-color: $--color-danger;
  &:focus {
     border-color: $--color-danger;
   }
  }
  }

    .yun-message-box__status {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    font-size: 24px !important;

  &::before {
   // 防止图标切割
   padding-left: 1px;
   }

    + .yun-message-box__message {
      padding-left: 36px;
      padding-right: 12px;
    }

  &.yun-icon-success {
     color: $--messagebox-success-color;
   }

  &.yun-icon-info {
     color: $--messagebox-info-color;
   }

  &.yun-icon-warning {
     color: $--messagebox-warning-color;
   }

  &.yun-icon-error {
     color: $--messagebox-danger-color;
   }
  }

    .yun-message-box__message {
    margin: 0;
      padding-top: 30*$length;

  & .yun-message-box__message_word {
      margin: 0;
    padding-top: 10*$length;

    @include fontStyle(14,24,500,#2f2f2f,center)
    }
  }

    .yun-message-box__errormsg {
    color: $--color-danger;
    font-size: $--messagebox-error-font-size;
    min-height: 18px;
    margin-top: 2px;
  }

    .yun-message-box__btns {
    padding: 38px 82px;
    text-align: right;
      @extend %flex-row-spb;
           .yun-message-box__btn1{
             cursor:pointer;
        width: 98*$length;
        height:36*$length;
        border-radius:4px;
        background-color: #75D098;
        @include fontStyle(14,36,500,#fff,center);
      }
      .yun-message-box__btn2{
        cursor:pointer;
        width: 98*$length;
        height:36*$length;
        border-radius:4px;
        background-color: #fff;
        border:1px solid #efefef;
        @include fontStyle(14,36,500,#666,center);
      }


      & button:nth-child(2) {
      margin-left: 10px;
    }
  }

    .yun-message-box__btns-reverse {
    flex-direction: row-reverse;
  }

  // centerAlign 布局
    .yun-message-box--center {
    padding-bottom: 30px;

    .yun-message-box__header {
      padding-top: 30px;
    }

    .yun-message-box__title {
      position: relative;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .yun-message-box__status{
      position: relative;
      top: auto;
      padding-right: 5px;
      text-align: center;
      transform: translateY(-1px);
    }

    .yun-message-box__message {
      margin-left: 0;
    }

    .yun-message-box__content .yun-message-box__btns {
      text-align: center;
    }

    .yun-message-box__content {
      $padding-horizontal: $--msgbox-padding-primary + 12px;

      padding-left: $padding-horizontal;
      padding-right: $padding-horizontal;
    }
  }
  }



  .msgbox-fade-enter-active {
    animation: msgbox-fade-in .3s;
  }

  .msgbox-fade-leave-active {
    animation: msgbox-fade-out .3s;
  }

  @keyframes msgbox-fade-in {
    0% {
      transform: translate3d(0, -20px, 0);
      opacity: 0;
    }
    100% {
      transform: translate3d(0, 0, 0);
      opacity: 1;
    }
  }

  @keyframes msgbox-fade-out {
    0% {
      transform: translate3d(0, 0, 0);
      opacity: 1;
    }
    100% {
      transform: translate3d(0, -20px, 0);
      opacity: 0;
    }
  }

</style>
